﻿/*

	Description:Create the Atlas of emojis and its data texture.

	How to use?
	1)
		Put all emojies in Asset/Framework/Resource/Emoji/Input.
		Multi-frame emoji name format : Name_Index.png , Single frame emoji format: Name.png
	2)
		Excute EmojiText->Build Emoji from menu in Unity.
	3)
		It will outputs two textures and a txt in Emoji/Output.
		Drag emoji_tex to "Emoji Texture" and emoji_data to "Emoji Data" in UGUIEmoji material.
	4)
		Repair the value of "Emoji count of every line" base on emoji_tex.png.
	5)
		It will auto copys emoji.txt to Resources, and you can overwrite relevant functions base on your project.
*/

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.IO;

public class Txt_IconTool
{
    private const string OutputPath = "Assets/TextIcon/Data/";
    private const string InputPath = "/Textures/";
    private const string Txt_Icon = "Txt_Icon";
    private const string Txt_Data = "Txt_Data";
    private const string Icon_Data = "Icon_Data";

    private static readonly Vector2[] AtlasSize = new Vector2[]{
        new Vector2(32,32),
        new Vector2(64,64),
        new Vector2(128,128),
        new Vector2(256,256),
        new Vector2(512,512),
        new Vector2(1024,1024),
        new Vector2(2048,2048)
    };

    struct EmojiInfo
    {
        public string key;
        public string x;
        public string y;
        public string size;
    }
    private const int IconSize = 128;//the size.

    [MenuItem("Tools/一键生成文字图集")]
    public static void BuildTxtIcon()
    {
        bool hasProtection = EditorUtility.DisplayDialog("使用手册",
            "素材放入 :Assets/Textures\n\n图片格式: name.PNG\n\n图片尺寸: 128*128 (修改尺寸,须告知)\n\n生成: 点击'一键生成文字图集'按钮" +
            "\n\nUI组件名: UITextIcon_\n\n使用方式: 大括号包裹图片名 例:{name}\n\n序列帧图命名格式: name_1,name_2等等...", "生成");
        if (hasProtection == false)
        {
            return;
        }

        // List<char> keylist = new List<char> ();
        // for(int i = 0; i<100; i++)
        // {
        // 	keylist.Add(i.ToString());
        // }
        // for (int i = 48; i <= 57; i++) {
        // 	keylist.Add (System.Convert.ToChar(i));//0-9
        // }
        // for (int i = 65; i <= 90; i++) {
        // 	keylist.Add (System.Convert.ToChar(i));//A-Z
        // }
        // for (int i = 97; i <= 122; i++) {
        // 	keylist.Add (System.Convert.ToChar(i));//a-z
        // }

        //search all emojis and compute they frames.
        Dictionary<string, int> sourceDic = new Dictionary<string, int>();
        string[] files = Directory.GetFiles(Application.dataPath + InputPath, "*.png");
        // 设置图片格式
        foreach (var item in files)
        {
            TextureImporter currentTexture = AssetImporter.GetAtPath(item.Replace(Application.dataPath, "Assets")) as TextureImporter;
            currentTexture.textureType = TextureImporterType.Default;
            currentTexture.textureShape = TextureImporterShape.Texture2D;
            currentTexture.sRGBTexture = true;
            currentTexture.alphaSource = TextureImporterAlphaSource.FromInput;
            currentTexture.alphaIsTransparency = false;
            currentTexture.isReadable = true;
            currentTexture.wrapMode = TextureWrapMode.Clamp;
            currentTexture.filterMode = FilterMode.Bilinear;
            currentTexture.SaveAndReimport();
        }

        for (int i = 0; i < files.Length; i++)
        {
            string[] strs = files[i].Split('/');
            string[] strs2 = strs[strs.Length - 1].Split('.');
            string filename = strs2[0];

            string[] t = filename.Split('_');
            string id = t[0];
            if (sourceDic.ContainsKey(id))
            {
                sourceDic[id]++;
            }
            else
            {
                sourceDic.Add(id, 1);
            }
        }

        //create the directory if it is not exist.
        if (!Directory.Exists(OutputPath))
        {
            Directory.CreateDirectory(OutputPath);
        }

        Dictionary<string, EmojiInfo> emojiDic = new Dictionary<string, EmojiInfo>();

        int totalFrames = 0;
        foreach (int value in sourceDic.Values)
        {
            totalFrames += value;
        }
        Vector2 texSize = ComputeAtlasSize(totalFrames);
        Texture2D newTex = new Texture2D((int)texSize.x, (int)texSize.y, TextureFormat.ARGB32, false);
        Texture2D dataTex = new Texture2D((int)texSize.x / IconSize, (int)texSize.y / IconSize, TextureFormat.ARGB32, false);
        int x = 0;
        int y = 0;
        int keyindex = 0;
        foreach (string key in sourceDic.Keys)
        {

            for (int index = 0; index < sourceDic[key]; index++)
            {

                string path = "Assets" + InputPath + key;
                if (sourceDic[key] == 1)
                {
                    path += ".png";
                }
                else
                {
                    path += "_" + (index + 1).ToString() + ".png";
                }

                Texture2D asset = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
                Color[] colors = asset.GetPixels(0);

                for (int i = 0; i < IconSize; i++)
                {
                    for (int j = 0; j < IconSize; j++)
                    {
                        newTex.SetPixel(x + i, y + j, colors[i + j * IconSize]);
                    }
                }

                string t = System.Convert.ToString(sourceDic[key] - 1, 2);
                float r = 0, g = 0, b = 0;
                if (t.Length >= 3)
                {
                    r = t[2] == '1' ? 0.5f : 0;
                    g = t[1] == '1' ? 0.5f : 0;
                    b = t[0] == '1' ? 0.5f : 0;
                }
                else if (t.Length >= 2)
                {
                    r = t[1] == '1' ? 0.5f : 0;
                    g = t[0] == '1' ? 0.5f : 0;
                }
                else
                {
                    r = t[0] == '1' ? 0.5f : 0;
                }

                dataTex.SetPixel(x / IconSize, y / IconSize, new Color(r, g, b, 1));

                if (!emojiDic.ContainsKey(key))
                {
                    EmojiInfo info;
                    info.key = "{" + key + "}";
                    info.x = (x * 1.0f / texSize.x).ToString();
                    info.y = (y * 1.0f / texSize.y).ToString();
                    info.size = (IconSize * 1.0f / texSize.x).ToString();

                    emojiDic.Add(key, info);
                    keyindex++;
                }

                x += IconSize;
                if (x >= texSize.x)
                {
                    x = 0;
                    y += IconSize;
                }
            }
        }

        byte[] bytes1 = newTex.EncodeToPNG();
        string outputfile1 = OutputPath + Txt_Icon + ".png"; ;
        File.WriteAllBytes(outputfile1, bytes1);

        byte[] bytes2 = dataTex.EncodeToPNG();
        string outputfile2 = OutputPath + Txt_Data + ".png"; ;
        File.WriteAllBytes(outputfile2, bytes2);
        using (StreamWriter sw = new StreamWriter(OutputPath + Icon_Data + ".txt", false))
        {
            sw.WriteLine("Key\tFrames\tX\tY\tSize");
            foreach (string key in emojiDic.Keys)
            {
                sw.WriteLine(emojiDic[key].key + "\t" + sourceDic[key] + "\t" + emojiDic[key].x + "\t" + emojiDic[key].y + "\t" + emojiDic[key].size);
            }
            sw.Close();
        }

        AssetDatabase.Refresh();
        FormatTexture();

        EditorUtility.DisplayDialog("Success", "一键生成图集成功!", "OK");
    }

    private static Vector2 ComputeAtlasSize(int count)
    {
        long total = count * IconSize * IconSize;
        for (int i = 0; i < AtlasSize.Length; i++)
        {
            if (total <= AtlasSize[i].x * AtlasSize[i].y)
            {
                return AtlasSize[i];
            }
        }
        return Vector2.zero;
    }

    private static void FormatTexture()
    {
        TextureImporter emojiTex = AssetImporter.GetAtPath(OutputPath + Txt_Icon + ".png") as TextureImporter;
        emojiTex.filterMode = FilterMode.Point;
        emojiTex.mipmapEnabled = false;
        emojiTex.sRGBTexture = true;
        emojiTex.alphaSource = TextureImporterAlphaSource.FromInput;
        emojiTex.textureCompression = TextureImporterCompression.Uncompressed;
        emojiTex.SaveAndReimport();

        TextureImporter emojiData = AssetImporter.GetAtPath(OutputPath + Txt_Data + ".png") as TextureImporter;
        emojiData.filterMode = FilterMode.Point;
        emojiData.mipmapEnabled = false;
        emojiData.sRGBTexture = false;
        emojiData.alphaSource = TextureImporterAlphaSource.None;
        emojiData.textureCompression = TextureImporterCompression.Uncompressed;
        emojiData.SaveAndReimport();
    }
}
